/*
MIT License

Copyright (c) 2021 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,

https://bmstu.codes/lsx/simodo
*/

#ifndef simodo_interpret_ExpressionPrimitives_interface
#define simodo_interpret_ExpressionPrimitives_interface

/*! \file ExpressionPrimitives_interface.h
    \brief .
*/

#include "simodo/interpret/SemanticModule_interface.h"
#include "simodo/interpret/StackOfNames_interface.h"
#include "simodo/interpret/Notification_interface.h"
#include "simodo/interpret/FlowLayerInfo.h"

#include "simodo/inout/reporter/Reporter_abstract.h"

#include <functional>

namespace simodo::interpret
{
    inline const std::u16string SPEC_NAME_INITIAL_VALUE { u"initial_value" };
    inline const std::u16string SPEC_NAME_BUILT_IN_TYPE { u"built_in_type" };

    // inline const std::u16string MARK_NAME_LOCAL_SCOPE    { u"local_scope" };
    // inline const std::u16string MARK_NAME_MODULE_SCOPE   { u"module_scope" };

    /**
     * @brief .
    */
    class ExpressionPrimitives_interface
    {
    public:
        virtual ~ExpressionPrimitives_interface() = default;

        virtual const variable::Value & return_value() const  = 0;
        virtual void                    setReturnValue(const variable::Value & value) = 0;

        virtual variable::Variable      convertVariable(const variable::Variable & var, 
                                                variable::ValueType type,
                                                bool need_copy = false) const = 0;
        virtual std::shared_ptr<variable::Object> self() = 0;
        virtual std::shared_ptr<variable::Object> makeSelf() = 0;
        virtual void                    callPreparedFunction(
                                                Interpret_interface * inter,
                                                boundary_index_t boundary_index, 
                                                Notification_interface & visitor,
                                                bool invoke) = 0;
        virtual void                    callPreparedFunction(
                                                boundary_index_t boundary_index, 
                                                Notification_interface & visitor,
                                                bool invoke,
                                                const std::function<void(const FlowLayerInfo &)> callback) = 0;

        virtual void                    assignVariable(variable::Variable & lvalue_origin, 
                                                const variable::Variable & rvalue_origin,
                                                bool need_copy = false) = 0;
        virtual void                    assignArray(variable::Variable & lvalue_origin, 
                                                const variable::Variable & rvalue_origin,
                                                bool need_copy) = 0;
        virtual void                    assignObject(variable::Variable & lvalue_origin, 
                                                const variable::Variable & rvalue_origin,
                                                bool need_copy) = 0;

        virtual void                    print(bool need_detailed_report) const = 0;
        /// \todo Метод дублирует функцию из variable!
        virtual std::u16string          toString(const variable::Value & value, 
                                                bool need_whole_info=false, 
                                                bool quote_strings=false) const = 0;
    };
}

#endif // simodo_interpret_ExpressionPrimitives_interface
